/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package entities;

import java.io.Serializable;
import java.util.*;

/**
 *
 * @author Dragan Sahpaski
 */
public class Query implements Serializable {

    private List<Condition> where = new ArrayList<Condition>();
    private List<Atribute> groupby = new ArrayList<Atribute>();
    private List<ViewGene> usableViews = new ArrayList<ViewGene>();

    public Query(Domain domain, List<Condition> where, List<Atribute> groupby) {
        this.where = where;
        this.groupby = groupby;
        List<ViewGene> allViews = domain.getViewGraph().getAllViews();
        for (ViewGene view : allViews) {
            if (isViewUsable(view)) {
                usableViews.add(view);
            }
        } // end Fill usable views
    }

    private boolean isViewUsable(ViewGene view) {
        for (Atribute a : groupby) {
            boolean found = false;
            for (Table dimRelation : view.getFKRelations()) {
                for (Table table : dimRelation) {
                    if (a.getTable().equals(table)) {
                        found = true;
                        break;
                    }
                }
            }
            // atribute not found in view.dimensions
            if (!found) {
                return false;
            }
        }
        return true;
    }

    public List<Atribute> getGroupby() {
        return groupby;
    }

    public List<Condition> getWhere() {
        return where;
    }

    public List<ViewGene> getUsableViews() {
        return usableViews;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Query other = (Query) obj;
        boolean areEqual = true;
        for (Condition c1 : where) {
            boolean notEntered = true;
            for (Condition c2 : other.getWhere()) {
                if (c1.getAtribute().getName().equals(c2.getAtribute().getName())) {
                    if (c1.getPredicate().equals(c2.getPredicate())) {
                        notEntered = false;
                        break;
                    }
                }
            }
            if (notEntered) {
                areEqual = false;
                break;
            }
        }
        if (areEqual == true) {
            for (Atribute a1 : groupby) {
                boolean notEntered = true;
                for (Atribute a2 : other.getGroupby()) {
                    if (a1.getName().equals(a2.getName())) {
                        notEntered = false;
                        break;
                    }
                }
                if (notEntered) {
                    areEqual = false;
                    break;
                }
            }
        }
        return areEqual;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 47 * hash + (this.where != null ? this.where.hashCode() : 0);
        hash = 47 * hash + (this.groupby != null ? this.groupby.hashCode() : 0);
        return hash;
    }

    @Override
    public String toString() {
        String str = "SELECT:";
        for (Atribute a : this.getGroupby()) {
            str += a.getName() + ", ";
        }
        str += "\n\tWHERE: ";
        for (Condition c : this.getWhere()) {
            str += c + " ";
        }
        str = str.substring(0, str.length() - 1);
        return str;
    }
}
